home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / docs / corsoguide / doslibrary-4.txt < prev    next >
Text File  |  1992-09-03  |  9KB  |  195 lines

  1. La dos.library
  2.  
  3. Programmando in C la dos.library costituisce l'unica eccezione a quanto
  4. detto prima sulle librerie; infatti non vi è bisogno di aprirla perché
  5. l'apertura e la chiusura vengono automaticamente effettuati dal
  6. compilatore; questo per mantenere la compabilità con lo standard ANSI C
  7. (e quindi garantire la portabilità dei programmi); infatti lo standard
  8. prevede di gestire files senza bisogno di aprire e chiudere alcunché;
  9. apertura e chiusura che devono quindi essere realizzate in maniera
  10. trasparente al programmatore. Come avrete capito la dos.library mette a
  11. disposizione le funzioni per gestire il DOS (Disk Operating System =
  12. Sistema Operativo del Disco), cioè gestione dei files, directory, drive
  13. et similia. Iniziamo subito con la gestione dei files, ed in particolare
  14. con la funzione che permette di aprirne uno:
  15.  
  16. file = Open(nomefile,modalità);
  17.  
  18. dove nomefile è il puntatore alla stringa contenente il nome del file o
  19. del dispositivo (tipo CON: o RAW:) completo di path; modalità indica la
  20. modalità appunto con cui aprire il file e può valere MODE_OLDFILE, per
  21. aprire un file già esistente per la lettura e scrittura (se il file non
  22. esiste verrà segnalato un errore), MODE_NEWFILE che crea un nuovo file
  23. per lettura e scrittura (se il file esiste già verra inizializzato
  24. comunque); ed infine MODE_READWRITE che apre un file, sempre per operazioni
  25. sia di lettura che di scrittura in modalità spartita (ciò significa che lo
  26. stesso file potrà essere aperto anche da altri processi, mentre per le
  27. precedenti modalità il file veniva bloccato, cioè altri processi non
  28. possono accedervi fino a quando non viene chiuso dal programma che lo usa
  29. attualmente); file è il puntatore ad una struttura FileHandle che contiene
  30. tutte le informazioni relative al file aperto; informazioni che
  31. necessitano a tutte le altre funzioni che operano sui file, per cui
  32. tale puntatore dovrà essere passato a tutte le funzioni che verranno
  33. chiamate successivamente; se il valore ritornato da Open è nullo, allora il
  34. file non è stato aperto per qualche motivo, per cui si è verificato un
  35. errore; vediamo un esempio:
  36.  
  37. struct FileHandle *Fh;
  38.   .
  39.   .
  40. if ((Fh = Open("ram:pippo",MODE_OLDFILE)) == NULL)
  41. {
  42.   printf("Non posso aprire il file pippo.\n");
  43.   exit(1);
  44. }
  45.  
  46. Dopo aver finito di utilizzare il file, occorre chiuderlo con la seguente
  47. funzione:
  48.  
  49. Close(file);
  50.  
  51. dove file è il puntatore a FileHandle ritornato dalla rispettiva funzione
  52. Open. La volta scorsa abbiamo parlato delle funzioni della dos.library per
  53. aprire e chiudere un file, le prossime istruzioni da esaminare riguardano
  54. la gestione di quest'ultimo; i files nell'AmigaDOS vengono gestiti sia ad
  55. accesso sequenziale che casuale (random); ciò significa che all'apertura
  56. del file, il cursore che segna la lettura è posizionato all'inizio di
  57. quest'ultimo e, man mano che si effettuano operazioni di lettura o di
  58. scrittura, quest'ultimo si posiziona alla fine della lunghezza dell'ultima
  59. operazione realizzata; in questa maniera si sfrutta un accesso sequenziale
  60. al file, esiste tuttavia un metodo per posizionarsi in un qualsiasi punto
  61. del file e utilizzare così un accesso casuale. La prima funzione da
  62. analizzare è Read che, come si può intuire dal nome, realizza l'operazione
  63. di lettura:
  64.  
  65. LungAttuale = Read(file,buffer,lunghezza);
  66.  
  67. dove file è il puntatore alla struttura FileHandle ritornata dalla funzione
  68. Open, buffer è un puntatore ad un buffer in memoria che conterrà i dati da
  69. leggere, e lunghezza il numero di bytes da leggere dal file; il parametro
  70. ritornato LungAttuale indica il numero di bytes effettivamente letti
  71. dall'operazione di Read; normalmente tale valore è positivo e serve a
  72. verificare che il numero di bytes letti equivale effettivamente a quello
  73. richiesto (in caso contrario si sarà raggiunto l'end-of-file); se tale
  74. numero vale zero significa che ci si trova già sull'end-of-file e quindi
  75. non è possibile leggere alcun byte; se tale valore risulta infine -1
  76. significa che si è verificato un errore; osserviamo immediatamente un
  77. esempio:
  78.  
  79. struct FileHandle *file;
  80. LONG len;
  81. UBYTE buffer[1000];
  82.   .
  83.   .
  84. len = Read(file,buffer,1000);
  85. if (len < 0) printf("Errore\n");
  86. else if (len < 1000) printf("Letti meno bytes, raggiunto EOF");
  87.  
  88. questo esempio tenta di leggere 1000 bytes dal file identificato dalla
  89. struttura FileHandle denominato 'file' e di inserirlo nel buffer denominato
  90. 'buffer' (che nella fattispecie è creato come vettore); se il valore
  91. ritornato len è negativo viene stampato su video un errore, se è inferiore
  92. a 1000 viene avvisato l'utente sempre con un messaggio.
  93. La seconda istruzione da esaminare è Write che serve per la scrittura in un
  94. file; la sintassi è:
  95.  
  96. LungRitorno = Write(file,buffer,lunghezza);
  97.  
  98. dove 'file' ricopre il solito significato, 'buffer' è il puntatore al buffer
  99. contenente i dati da scrivere e 'lunghezza' indica il numero di byte da
  100. scrivere; 'LungRitorno' indica il numero di bytes realmente scritti sul
  101. file; anche in questo caso in presenza di errore il valore ritornato è -1;
  102. l'esempio viene riportato qui di seguito:
  103.  
  104. struct FileHandle *file;
  105. LONG len;
  106. UBYTE buffer[1000];
  107.   .
  108.   .
  109. len = Write(file,buffer,1000);
  110. if (len < 0) printf("Errore\n");
  111.  
  112. Le istruzioni Read e Write sono non bufferizzate, ciò significa che se
  113. leggo un solo byte alla volta il dos accederà ogni volta al file impiegando
  114. così molto tempo; una vecchia soluzione per risolvere questo problema era
  115. leggere un blocco di bytes riponendolo in un buffer e da lì prelevare i
  116. singoli caratteri; dalla versione 2.0 del sistema operativo (V36) sono
  117. previste però due funzioni che permettono di leggere e scrivere un byte
  118. alla volta con bufferizzazione implementata dal DOS: FGetC e FPutC. La
  119. prima preleva un carattere dalla poszione corrente del file e il secondo
  120. inserisce un carattere nella posizione corrente del file; la sintassi di
  121. queste è:
  122.  
  123. carattere = FGetC(file);
  124.  
  125. dove 'carattere' è il byte letto dal file puntato da 'file'.
  126.  
  127. carattere1 = FPutC(file,carattere2);
  128.  
  129. dove 'carattere2' è il byte da scrivere nel file puntato da 'file'; il
  130. valore ritornato 'carattere1', o è identico a carattere2 o corrisponde a
  131. EOF se si è verificato errore.
  132. Dato che con queste operazioni viene effettuata una bufferizzazione, se dopo
  133. la chiamata di una di queste si ha intenzione di utilizzare un Read o un
  134. Write (che non sono bufferizzate), occorre effettuare un operazione di
  135. scarico del buffer: Flush;
  136.  
  137. successo = Flush(file);
  138.  
  139. dove il valore ritornato indica il successo dell'operazione.
  140. Un'altra operazione importante legata a quelle bufferizzate è UnGetC che
  141. permette da inserire nel buffer un qualsiasi byte e che quindi verrà
  142. acquisito nella prossima operazione di lettura (se questa è bufferizzata);
  143.  
  144. valore = UnGetC(file,carattere);
  145.  
  146. 'carattere' è il byte che viene inserito nel buffer di I/O; se questi
  147. vale -1 allora verrà reinserito nel buffer l'ultimo byte letto (sempre da
  148. operazione bufferizzata e vale a dire FGetC); il parametro ritornato
  149. 'valore', indica il carattere inserito nel buffer o FALSE se tale carattere
  150. non può essere inserito nel buffer.
  151. Come abbiamo accennato, vi è la possibilità di accedere casualmente al file
  152. mediante un istruzione che ci permette di spostarci in un punto qualsiasi di
  153. quest'ultimo: Seek la cui sintassi è:
  154.  
  155. vecchiapos = Seek(file,posizione,modalità);
  156.  
  157. Il valore 'vecchiapos' ritornato indica la posizione assoluta (rispetto
  158. all'inizio del file) attuale, prima che l'operazione di spostamento abbia
  159. luogo; se il valore ritornato risulta -1, lo spostamento non è stato
  160. effettuato per qualche motivo (indice uscito fuori dai limiti del file);
  161. 'modalità' indica il tipo di riferimento da adottare per lo spostamento,
  162. che può valere OFFSET_BEGINNING (inizio del file), OFFSET_CURRENT
  163. (corrente posizione del file) o OFFSET_END (fine del file); 'posizione'
  164. è il valore che indica la nuova posizione da assumere rispetto al
  165. riferimento indicato da 'modalità' e può essere sia negativo che positivo,
  166. vediamo qualche esempio:
  167.  
  168. struct FileHandle *file;
  169. LONG vecpos,pos;
  170.   .
  171.   .
  172. vecpos = Seek(file,0,OFFSET_BEGINNING);
  173. /* Posizionati all'inizio del file */
  174.   .
  175. vecpos = Seek(file,0,OFFSET_END);
  176. /* Posizionati alla fine del file */
  177.   .
  178. vecpos = Seek(file,1,OFFSET_CURRENT);
  179. /* Posizionati di un byte avanti alla posizione corrente */
  180.   .
  181. vecpos = Seek(file,-1,OFFSET_END);
  182. /* Posizionati un byte prima della fine del file */
  183.  
  184. Fino ad adesso è stato sempre indicato come dopo ogni operazione DOS, sia
  185. possibile rilevare se quest'ultima è incorsa in un errore o meno, ma come
  186. fare per capire qual è l'errore che è stato causato? La funzione DOS che si
  187. occupa di identificare l'errore è IoErr:
  188. (vp1)errore = IoErr();
  189. (vp5)Dove errore è il codice dell'errore verificatosi; attenzione però se
  190. l'operazione ha avuto successo e quindi non si è verificato alcun errore,
  191. nulla si sà sul valore ritornato.
  192. Ci sono molte altre funzioni della dos.library alcuni delle quali
  193. importanti, che corrispondono a nuove caratteristiche del 2.0 (assegnamenti
  194. multipli ecc.), ma quelle esaminate sono quelle che utilizzerete più spesso.
  195.